package com.fbs.wowo.chat.service.imp;

import com.fbs.wowo.chat.entity.Friend;
import com.fbs.wowo.chat.mapper.FriendMapper;
import com.fbs.wowo.chat.service.FriendService;
import com.fbs.wowo.chat.vo.FriendInfo;
import com.fbs.wowo.chat.vo.MyFriend;
import com.fbs.wowo.exception.*;
import com.fbs.wowo.manage.entity.User;
import com.fbs.wowo.manage.mapper.UserMapper;
import com.fbs.wowo.util.rongcloud.RCMessage;
import com.fbs.wowo.util.rongcloud.RCUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * TODO 搜索号加id
 */
@Service("friendService")
@Transactional
public class FriendServiceImp implements FriendService {
    private static final String GROUP = "我的好友";

    /**
     * 拒绝好友请求
     *
     * @param friend
     */
    @Override
    public void reject(Friend friend) {
        // 参数为空
        if (friend == null || !StringUtils.hasText(friend.getFid()) || !StringUtils.hasText(friend.getMid()))
            throw new GivenNullParamException();
        Friend f = findFriendById(friend.getMid(), friend.getFid());
        validateFriend(f);

        // 发送融云消息
        RCUtils.friendMsg(RCUtils.RejectResponse, friend.getMid(), friend.getFid(), "对方拒绝你的好友请求");
    }

    /**
     * 添加好友
     * 判断是否已存在
     *
     * mid fid
     * fid mid
     */
    @Override
    public void join(Friend friend) throws GivenNullParamException, EntityHasExistException {
        // 参数为空
        if (friend == null || !StringUtils.hasText(friend.getFid()) || !StringUtils.hasText(friend.getMid()))
            throw new GivenNullParamException();
        // 自己不能加自己
        validateEqualId(friend.getMid(), friend.getFid());
        // 数据已存在
        if (findFriendByIdValid(friend.getMid(), friend.getFid()) != null) {
            throw new EntityHasExistException(ErrorCode.ERR_HAS_BEEN_FRIEND);
        }
        // 已经发过好友请求，现在是验证
        Friend f = findFriendById(friend.getMid(), friend.getFid());
        if (f != null) {
            // 自己不能通过自己的好友请求
            // 如果误删好友再加对方,对方需要通过
//            validateEqualId(friend.getMid(), f.getMid());
            f.setValid((byte) 1);
            initialFriendInfo(friend, f);
            updateFriend(f);
            return;
        }
        // 未发过好友请求 直接添加好友
        // 去除空格等影响
        initialFriendInfo(friend, friend);
        // 插入
        friend.setValid((byte) 1);
        saveFriend(friend);

        // 发送融云消息
        RCUtils.friendMsg(RCUtils.AcceptResponse, friend.getMid(), friend.getFid(), "对方同意你的好友请求");
    }


    /**
     * 添加好友，发送验证消息
     * 发送验证，创建好友，valid 0 备注
     * 添加好友 valid 1
     * 查找 valid 1
     * 删除好友 valid 0
     * @param friend 好友信息
     * @param content 验证消息
     */
    @Override
    public void invite(Friend friend, String content) throws GivenNullParamException, NoSuchDataException, InputVerifyFailedException {
        if (friend == null) throw new GivenNullParamException();
        // 我的名字
        User u = validateUser(friend.getMid());
        validateUser(friend.getFid());
        // 如果两个id一样，不能添加自己为好友
        validateEqualId(friend.getMid(), friend.getFid());
        // 1. 判断两人是否已经是好友
        Friend f = findFriendByIdValid(friend.getMid(), friend.getFid());
        if (f != null) throw new InputVerifyFailedException(ErrorCode.ERR_HAS_BEEN_FRIEND);

        // 如果已经发送过好友验证但未通过验证 就再发一次验证，但不往数据库插入数据
        if (findFriendById(friend.getMid(), friend.getFid()) != null) return;
        // 创建好友关系
        if (StringUtils.hasText(friend.getMyNickname())) friend.setMyNickname(friend.getMyNickname());
        friend.setMyGroup(GROUP);
        friend.setValid((byte) 0);
        saveFriend(friend);

        // 2. 融云：发送好友验证
        RCMessage rcMsg = new RCMessage(friend.getMid(), friend.getFid(), u.getName(), 2, null, null, content, RCUtils.REPLY_FRIEND);
        RCUtils.invite(rcMsg);
//        RCUtils.friendMsg(friend.getMid(), friend.getFid(), RCUtils.Request, "加你好友");
    }

    /**
     * 好友列表
     */
    @Override
    public List<MyFriend> selectAll(@NotBlank String id) throws GivenNullParamException, NoSuchDataException {
        validateUser(id);
        return friendMapper.selectAll(id);
    }

    /**
     * 按主键查找好友关系
     */
    @Override
    public Friend selectByPrimaryKey(@NotBlank String mid, @NotBlank String fid) throws GivenNullParamException, NoSuchDataException {
        Friend friend = findFriendById(mid, fid);
        validateFriend(friend);
        return friend;
    }
    /**
     * 按主键查找好友关系 只取审核后的
     */
    @Override
    public Friend selectByPrimaryKeyValid(@NotBlank String mid, @NotBlank String fid) throws GivenNullParamException, NoSuchDataException {
        validateString(mid);
        validateString(fid);
        validateEqualId(mid, fid);
        Friend friend = findFriendByIdValid(mid, fid);
        validateFriend(friend);
        return friend;
    }

    // 好友列表
    public List<Friend> findByUserId(String mid, String fid) {
        validateUser(mid);
        validateUser(fid);
        // 查看用户信息，是否好友，备注，
        return null;
    }

    /**
     * 删除好友
     */
    @Override
    public void deleteByPrimaryKey(@NotBlank String mid, @NotBlank String fid) throws GivenNullParamException, NoSuchDataException {
        Friend friend = findFriendByIdValid(mid, fid);
        validateFriend(friend);
        friend.setValid((byte) 0);
        updateFriend(friend);
    }

    /**
     * 修改备注
     */
    @Override
    public void updateNickname(@NotBlank String mid, @NotBlank String fid, @NotBlank String nickname) throws GivenNullParamException, NoSuchDataException {
        validateString(mid);
        validateString(fid);
        validateString(nickname);
        // 需要判断记录是fNickname还是myNickname
        Friend f = selectByPrimaryKey(mid, fid);
        if (f.getFid().equals(fid)) {
            f.setMyNickname(nickname);
        } else {
            f.setfNickname(nickname);
        }
        updateFriend(f);
    }

    /**
     * 查看好友详情
     *
     * 是否是好友
     * 头像
     * 性别
     * 昵称
     * 备注
     * 简介
     *
     * @param mid 我的id
     * @param fid 要查看的人的id
     * @return 查看的人呢的信息
     */
    @Override
    public FriendInfo friendInfo(String mid, String fid) throws GivenNullParamException, NoSuchDataException, InputVerifyFailedException {
        FriendInfo friendInfo = new FriendInfo();
        validateUser(mid);
        User user = validateUser(fid);
        validateString(mid);
        validateString(fid);

        Friend friend = findFriendByIdValid(mid, fid);
        if (friend == null) {
            friendInfo.setIsFriend(0);
            friendInfo.setNickname("");
        }
        else {
            friendInfo.setIsFriend(1);
            if (mid.equals(friend.getMid())) {
                friendInfo.setNickname(friend.getMyNickname());
            } else {
                friendInfo.setNickname(friend.getfNickname());
            }
        }
        friendInfo.setBrief(user.getBrief());
        friendInfo.setName(user.getName());
        friendInfo.setPhoto(user.getPhoto());
        friendInfo.setSex(user.getSex().intValue());
        return friendInfo;
    }


    /***********************************
     *
     *
     * 私有方法
     *
     *
     ***********************************/

    private void validateFriend(Friend friend) {
        if (friend == null) throw new NoSuchDataException(ErrorCode.ERR_NOT_FRIEND_YET);
    }

    private void initialFriendInfo(Friend friend, Friend f) {
        f.setMyNickname(StringUtils.hasText(friend.getMyNickname()) ? friend.getMyNickname() : null);
        f.setfNickname(null);

        // 默认备注
        if (!StringUtils.hasText(friend.getfGroup())) f.setfGroup(GROUP);
        if (!StringUtils.hasText(friend.getMyGroup())) f.setMyGroup(GROUP);
    }

    private void validateEqualId(String mid, String fid) {
        if (mid.equals(fid)) throw new InputVerifyFailedException(ErrorCode.ERR_YOURSELF_SHIP);
    }

    private void validateString(String str) throws GivenNullParamException {
        if (!StringUtils.hasText(str)) throw new GivenNullParamException();
    }

    /*************************************************
     *
     * 底层实现
     *
     *************************************************/

    private int saveFriend(Friend friend) {
        return friendMapper.insertSelective(friend);
    }

    private int updateFriend(Friend f) {
        return friendMapper.updateByPrimaryKeySelective(f);
    }

    private Friend findFriendById(String mid, String fid) throws GivenNullParamException, NoSuchDataException {
        return friendMapper.selectByPrimaryKey(mid, fid);
    }

    private Friend findFriendByIdValid(String mid, String fid) throws GivenNullParamException, InputVerifyFailedException {
        return friendMapper.selectByPrimaryKeyValid(mid, fid);
    }

    private User validateUser(String uid) throws GivenNullParamException, NoSuchDataException {
        validateString(uid);
        User user = userMapper.findByUserId(uid);
        if (user == null) throw new NoSuchDataException(ErrorCode.ERR_USER_NOT_EXIST);
        return user;
    }


    @Autowired
    private UserMapper userMapper;
    @Autowired
    private FriendMapper friendMapper;

}
